package edu.stanford.travelhard;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;

public class ImageAdapter extends BaseAdapter {
	
	private static final Comparator<LoadedMedia> FIRST_CAPTURED_COMP = new Comparator<LoadedMedia>() {
		public int compare(LoadedMedia lm1, LoadedMedia lm2) {
			return lm2.getMedia().getTimeCaptured().compareTo(lm1.getMedia().getTimeCaptured());
		}
    };
    
    private static final Comparator<LoadedMedia> LAST_CAPTURED_COMP = new Comparator<LoadedMedia>() {
		public int compare(LoadedMedia lm1, LoadedMedia lm2) {
			return lm1.getMedia().getTimeCaptured().compareTo(lm2.getMedia().getTimeCaptured());
		}
    };
    
    private static final Comparator<LoadedMedia> FIRST_PUBLISHED_COMP = new Comparator<LoadedMedia>() {
		public int compare(LoadedMedia lm1, LoadedMedia lm2) {
			Date lm1Published = lm1.getMedia().getTimePublished();
			Date lm2Published = lm2.getMedia().getTimePublished();
			
			if (lm1Published == null) {
				if (lm2Published == null) return 0;
				return -1;
			} else if (lm2Published == null) {
				return 1;
			}
			
			return lm2Published.compareTo(lm1Published);
		}
    };
    
    private static final Comparator<LoadedMedia> LAST_PUBLISHED_COMP = new Comparator<LoadedMedia>() {
		public int compare(LoadedMedia lm1, LoadedMedia lm2) {
			return FIRST_PUBLISHED_COMP.compare(lm2, lm1);
		}
    };
	
	public enum Order {
		FIRST_CAPTURED(FIRST_CAPTURED_COMP),
		LAST_CAPTURED(LAST_CAPTURED_COMP),
		FIRST_PUBLISHED(FIRST_PUBLISHED_COMP),
		LAST_PUBLISHED(LAST_PUBLISHED_COMP);
		
		private Comparator<LoadedMedia> comparator;
		
		private Order(Comparator<LoadedMedia> comparator) {
			this.comparator = comparator;
		}
	}
	
    private Context mContext;
    private ArrayList<LoadedMedia> mItems;
    private Order mOrder;
    
    public ImageAdapter(Context c, Order order) {
        mContext = c;
        mOrder = order;
        mItems = new ArrayList<LoadedMedia>();
    }
    
    /**
     * Adds the item in sorted order. Not the slickest way to
     * do it, but it'll do for now.
     * @param item
     */
    public void add(LoadedMedia item) {
    	int position = 0;
    	for (LoadedMedia mItem : mItems) {
    		if (mOrder.comparator.compare(item, mItem) > -1) {
    			break;
    		}
    		position++;
    	}
    	mItems.add(position, item);
    	
    	notifyDataSetChanged();
    }
    
    public void remove(LoadedMedia item) {
    	mItems.remove(item);
    	notifyDataSetChanged();
    }
    
    public LoadedMedia remove(Media item) {
    	LoadedMedia mItem = null;
    	int position = -1;
    	
    	for (int i = 0; i < mItems.size(); i++) {
    		if (mItems.get(i).getMedia().equals(item)) {
    			mItem = mItems.get(i);
    			position = i;
    			break;
    		}
    	}
    	
    	if (mItem != null) {
    		remove(position);
    		notifyDataSetChanged();
    	}
    	
    	return mItem;
    }
    
    public void remove(int pos) {
    	mItems.remove(pos);
    	notifyDataSetChanged();
    }
    
    public LoadedMedia get(int pos) {
    	if(pos >= 0 && pos < mItems.size()) {
    		return mItems.get(pos);
    	}
    	return null;
    }
    
	public int getCount() {
		return mItems.size();
	}

	public Object getItem(int position) {
		return this.get(position);
	}

	public long getItemId(int position) {
		return mItems.get(position).getMedia().getDBID();
	}

	public List<LoadedMedia> getItems() {
    	return mItems;
    }
	
	public Order getOrder() {
		return mOrder;
	}
	
    // create a new ImageView for each item referenced by the Adapter
    public View getView(int position, View convertView, ViewGroup parent) {
        ImageView imageView;
        if (convertView == null) {  // if it's not recycled, initialize some attributes
            imageView = new ImageView(mContext);
            imageView.setLayoutParams(new GridView.LayoutParams(150, 150));
            imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
            imageView.setPadding(5, 5, 5, 5);
        } else {
            imageView = (ImageView) convertView;
        }
        
		imageView.setImageBitmap(mItems.get(position).getThumbnail());
        return imageView;
    }
    
    public void setItems(ArrayList<LoadedMedia> media) {
    	mItems = media;
    	if (mItems != null) notifyDataSetChanged();
    }
    
    /**
     * Sets a new ordering on the elements in this
     * adapter and sorts them accordingly.
     * 
     * @param order
     */
    public void setOrder(Order order) {
    	if (mOrder == order) return;

    	mOrder = order;
    	Collections.sort(mItems, mOrder.comparator);

    	notifyDataSetChanged();
    }

}